1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.apache.tapestry5.ioc.util;
16
17 import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
18 import org.apache.tapestry5.ioc.internal.util.InheritanceSearch;
19
20 import java.util.Collection;
21 import java.util.List;
22 import java.util.Map;
23
24
25
26
27
28
29
30 public final class StrategyRegistry<A>
31 {
32 private final Class<A> adapterType;
33
34 private final boolean allowNonMatch;
35
36 private final Map<Class, A> registrations = CollectionFactory.newMap();
37
38 private final Map<Class, A> cache = CollectionFactory.newConcurrentMap();
39
40
41
42
43 private final Map<Class, Boolean> unmatched = CollectionFactory.newConcurrentMap();
44
45 private StrategyRegistry(Class<A> adapterType, Map<Class, A> registrations, boolean allowNonMatch)
46 {
47 this.adapterType = adapterType;
48 this.allowNonMatch = allowNonMatch;
49
50 this.registrations.putAll(registrations);
51 }
52
53
54
55
56
57
58
59 public static <A> StrategyRegistry<A> newInstance(Class<A> adapterType,
60 Map<Class, A> registrations)
61 {
62 return newInstance(adapterType, registrations, false);
63 }
64
65
66
67
68
69
70
71
72 public static <A> StrategyRegistry<A> newInstance(
73 Class<A> adapterType,
74 Map<Class, A> registrations, boolean allowNonMatch)
75 {
76 return new StrategyRegistry<A>(adapterType, registrations, allowNonMatch);
77 }
78
79 public void clearCache()
80 {
81 cache.clear();
82 unmatched.clear();
83 }
84
85 public Class<A> getAdapterType()
86 {
87 return adapterType;
88 }
89
90
91
92
93
94
95
96
97
98
99 public A getByInstance(Object value)
100 {
101 return get(value == null ? void.class : value.getClass());
102 }
103
104
105
106
107
108
109
110
111 public A get(Class type)
112 {
113
114 A result = cache.get(type);
115
116 if (result != null) return result;
117
118 if (unmatched.containsKey(type)) return null;
119
120
121 result = findMatch(type);
122
123
124
125
126 if (result != null)
127 {
128 cache.put(type, result);
129 } else
130 {
131 unmatched.put(type, true);
132 }
133
134 return result;
135 }
136
137 private A findMatch(Class type)
138 {
139 for (Class t : new InheritanceSearch(type))
140 {
141 A result = registrations.get(t);
142
143 if (result != null) return result;
144 }
145
146 if (allowNonMatch) return null;
147
148
149
150
151 List<String> names = CollectionFactory.newList();
152 for (Class t : registrations.keySet())
153 names.add(t.getName());
154
155 throw new UnknownValueException(String.format("No adapter from type %s to type %s is available.", type.getName(), adapterType.getName()), null, null,
156 new AvailableValues("registered types", registrations));
157 }
158
159
160
161
162 public Collection<Class> getTypes()
163 {
164 return CollectionFactory.newList(registrations.keySet());
165 }
166
167 @Override
168 public String toString()
169 {
170 return String.format("StrategyRegistry[%s]", adapterType.getName());
171 }
172 }